<template>
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>更换头像</span>
      </div>
      <div>
        <!-- 图片，用来展示用户选择的头像 -->
        <img v-if="!avatar" class="the_img" src="../../assets/images/avatar.jpg" alt="" />
        <!-- 这两段代码的意思是：当avatar不为空的时候，就执行下面那段代码，将avatar作为src的路径，显示指定的图片，如果avatar为空的时候，!取反就为true，就执行上面那段，显示一张默认图片 -->
        <img v-else :src="avatar" alt="" class="the_img">

        <!-- 按钮区域 -->
        <div class="btn-box">
          <input type="file" accept="image/*" style="display: none" ref="iptRef" @change="onFileChange" />
          <el-button type="primary" icon="el-icon-plus" @click="chooseImg">选择图片</el-button>
          <el-button type="success" icon="el-icon-upload" :disabled="avatar === ''" @click="uploadFn">上传头像</el-button>
        </div>
      </div>
    </el-card>
  </template>

<script>
import { updateUserAvatarAPI } from '@/api'
export default {
  name: 'UserAvatar',
  data () {
    return {
      avatar: '' // 这个变量用于保存图片链接/base64字符串
    }
  },
  methods: {
    // 选择图片的点击事件
    chooseImg () {
      // 目的：为了让type类型为file的input标签用它的JS代码来触发它自身的点击事件(导致它的默认行为：显示一个文件选择窗口)
      // 采用这种方式的原因：input[type=file]是一个原生标签，它的样式不太好改，所以得用这种方式
      this.$refs.iptRef.click() // click()是模拟点击，这里是当chooseImg被调用时，使得ref为iptRef的标签也被点击
    },
    // 确定选择图片
    onFileChange (e) { // e是原生的事件触发对象
      const files = e.target.files // 拿到用户选择的文件数组
      if (files.length === 0) {
        // 证明刚刚文件选择窗口打开了，但用户没有选择图片然后就直接点击确认关闭了选择窗口
      } else {
        // 证明用户选择了文件(默认只能选一个，如果选择多个，就需要给input标签添加额外的原生属性)
        // console.log(files[0])

        // 效果：选择的图片文件要给到img标签上，做到纯前端的预览
        // 方法一：将图片文件转换为内存临时(链接)地址(这个内存地址只能再js内存里用，不能发给后台)
        // 语法：URL.createObjectURL(文件)
        // 返回值
        // this.avatar = URL.createObjectURL(files[0])

        // 方法二：将图片文件转换为base64字符串(这个字符串可以发给后台)
        const fr = new FileReader()
        fr.readAsDataURL(files[0]) // 传入文件对象，开始读取成base64字符串
        fr.onload = (e) => { // onload是一个事件函数，这里是等待把文件读成base64字符串后会触发的事件
          this.avatar = e.target.result // 将最终的base64字符串复制给avatar
        }
      }
    },
    // 开始上传头像
    async uploadFn () {
      const { data: res } = await updateUserAvatarAPI(this.avatar)
      if (res.code !== 0) return this.$message.error(res.message) // 更新头像失败
      // 更新头像成功
      this.$message.success(res.message)
      // 通过调用vuex中actions中的getUserInfoActions方法重新让vuex获取下最新的用户数据
      this.$store.dispatch('getUserInfoActions')
    }
  }
}
</script>

  <style lang="less" scoped>
  .btn-box {
    margin-top: 10px;
  }
  .preview {
    object-fit: cover;
  }
  .the_img{
      width: 350px;
      height: 350px;
  }
  </style>
